# Title     : TODO
# Objective : TODO
# Created by: Administrator
# Created on: 2019/7/24

library(ggpubr)

library(ggrepel)
library(plyr)
library(gridExtra)
library(scales)
library(egg)
library(optparse)
library(grid)
library(cowplot)
library(tidyverse)
library(jsonlite)
library(extrafont)


createWhenNoExist <- function(f) {
  !dir.exists(f) && dir.create(f)
}

option_list <- list(
  make_option("--i", default = "AllMet_Raw.txt", type = "character", help = "metabolite data file"),
  make_option("--g", default = "group.txt", type = "character", help = "sample group file"),
  make_option("--pc", default = "", type = "character", help = "plot config file")
)
opt <- parse_args(OptionParser(option_list = option_list))

sampleInfo <- read_tsv(opt$g) %>%
  rename(SampleID = Sample) %>%
  select(c("SampleID", "ClassNote")) %>%
  mutate(ClassNote = as.character(ClassNote)) %>%
  mutate(ClassNote = factor(ClassNote, levels = unique(ClassNote)))

plotConfigJson <- fromJSON(opt$pc)

sampleColDf <- tibble(ClassNote = plotConfigJson$color$groups, col = plotConfigJson$color$colors)

sampleCols <- sampleColDf %>%
  deframe()

groups <- unique(sampleInfo$ClassNote)

parent <- "./"
fileName <- paste0(parent, "/AllMet_Test.csv")
outFileName <- paste0(parent, "/AllMet_Boxplot.pdf")

pValueData <- read.csv(fileName, header = T, stringsAsFactors = F, comment.char = "") %>%
  arrange(P)
names <- pValueData$Metabolite
data <- read_tsv(opt$i) %>%
  gather("SampleID", "Value", -Metabolite) %>%
  inner_join(sampleInfo, by = c("SampleID")) %>%
  filter(ClassNote %in% groups)

plotPoint <- plotConfigJson$layout$plotPoint %>%
  as.logical()
jitterAlpha <- plotConfigJson$layout$jitterAlpha %>%
  as.numeric()
outlierAlpha <- plotConfigJson$layout$outlierAlpha %>%
  as.numeric()
boxWidth <- plotConfigJson$layout$boxWidth %>%
  as.numeric()
width <- plotConfigJson$layout$width %>%
  as.numeric()
height <- plotConfigJson$layout$height %>%
  as.numeric()
xFont <- plotConfigJson$font$xFont
yFont <- plotConfigJson$font$yFont
mainTitleFont <- plotConfigJson$font$mainTitleFont
fontFamily <- plotConfigJson$font$fontFamily
plotSignificant <- plotConfigJson$layout$plotSignificant
baseFamily <- fontFamily
if (baseFamily == "SimSum") {
  font_import(paths = c("/usr/share/fonts/myFonts"), recursive = F, prompt = F)
}

testTb <- if (plotSignificant == "comparisons") {
  read_csv("testTb_comparisons.csv")
}else if (plotSignificant == "post_hoc") {
  read_csv("testTb_post_hoc.csv")
}

getP <- function(name) {
  pData <- data %>% filter(Metabolite == name)
  pValueDf <- pValueData %>% filter(Metabolite == name)

  p <- ggplot(pData) +
    theme_bw(base_size = 8, base_family = baseFamily) +
    theme(axis.text.x = element_text(size = xFont, vjust = 0.5),
          axis.text.y = element_text(size = yFont), legend.position = 'none',
          axis.title.y = element_text(size = 11), legend.margin = margin(t = 0.3, b = 0.1, unit = 'cm'),
          legend.text = element_text(size = 6), axis.title.x = element_text(size = 11), panel.grid.major = element_blank(),
          panel.grid.minor = element_blank(),
          plot.title = element_text(hjust = 0.5, size = mainTitleFont, family = baseFamily),
          panel.border = element_rect(size = 0.25)
    ) +
    xlab("") +
    ylab("") +
    ggtitle(paste0(pValueDf$Metabolite, "\n", "P=", scientific(pValueDf$P, 2))) +
    stat_boxplot(mapping = aes(x = ClassNote, y = Value), geom = "errorbar", width = 0.5) +
    scale_fill_manual("", values = sampleCols)

  if (plotSignificant == "comparisons" || plotSignificant == "post_hoc") {
    minY <- min(pData$Value)
    maxY <- max(pData$Value)
    yHeight <- (maxY - minY)
    useTestTb <- testTb %>%
      filter(Metabolite == name)
    comparisons <- groups %>%
      as.character() %>%
      combn(2) %>%
      asplit(2)
    compareNum <- comparisons %>%
      length()
    limitY <- c(minY, (maxY + yHeight * 0.1 * compareNum) * 1.025)
    p <- p +
      scale_y_continuous(limits = limitY) +
      stat_pvalue_manual(useTestTb, label = "p.signif")
  }

  if (plotPoint) {
    p <- p +
      geom_boxplot(mapping = aes(x = ClassNote, y = Value, fill = ClassNote), outlier.shape = NA) +
      geom_jitter(mapping = aes(x = ClassNote, y = Value, fill = ClassNote), size = 0.75, alpha = jitterAlpha)
  }else {
    p <- p +
      geom_boxplot(mapping = aes(x = ClassNote, y = Value, fill = ClassNote), outlier.size = 0.75, outlier.alpha = outlierAlpha, width = boxWidth)
  }

  return(p)
}

data
p <- names %>%
  map(getP)


pdf(outFileName, width = width, height = height)

for (i in seq(1, length(p), 9)) {
  plot.new()
  iEnd <- i + 8
  inP <- p[i:iEnd] %>%
    map(function(x) {
      if (is.null(x)) {
        p <- ggplot() + theme_void()
        p
      }else x
    })
  inEnd <- if (length(inP) < 3) {
    length(inP)
  }else 3
  inP[1:inEnd] = inP[1:inEnd] %>%
    map(~.x + theme(plot.margin = margin(t = 0.5, unit = "cm")))
  ggarrange(plots = inP, ncol = 3, newpage = F)
}

dev.off()
